home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Languguage OS 2
/
Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO
/
a_utils
/
perl
/
msds-prl
/
ptchds19.zoo
/
argv_asm
next >
Wrap
Text File
|
1992-02-23
|
10KB
|
365 lines
MS-DOS patches to perl.
Apply this patch to the standard perl source, version 4, patch level 19,
using "patch -p." Do this in the root directory of the perl source
distribution.
You can cat all these patches together and pipe the output to patch -p.
Len Reed
Holos Software, Inc.
..!gatech!holos0!lbr
holos0!lbr@gatech.edu
--------------------------------------
*** msdos/argv.asm.old Sun Feb 23 08:48:16 1992
--- msdos/argv.asm Thu Nov 14 08:56:28 1991
***************
*** 0 ****
--- 1,347 ----
+ ; Invoke MKS argument handler. If succcesful, return.
+ ; If unsuccessful, call MS-DOS __argv to process the command line.
+
+ ; Called by MS-DOS C startup code (crt0.obj in the C library).
+
+ ; This code used detailed knowledge of how the Microsoft C 6.0 startup
+ ; code works. That source is distributed with the compiler, in
+ ; lib/startup and lib/startup/dos, so we're not talking about a terrible
+ ; guessing game here.
+
+ ; This code contains no MKS or Microsoft copyrighted code.
+
+ ; This program is free software; you can redistribute it and/or
+ ; modify it under the terms of the GNU General Public License
+ ; (version 1), as published by the Free Software Foundation, and
+ ; found in the file 'LICENSE' included with this distribution.
+
+ ; This program is distributed in the hope that it will be useful,
+ ; but WITHOUT ANY WARRANTY; without even the implied warrant of
+ ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ ; GNU General Public License for more details.
+
+ ; You must assemble this file with masm flag
+ ; -dmmodel where model is one of {small, compact, medium, large}
+ ;
+ ifdef msmall
+ .model small
+ ARG equ 4
+ endif
+ ifdef mcompact
+ .model compact
+ ARG equ 4
+ endif
+ ifdef mmedium
+ .model medium
+ ARG equ 6
+ endif
+ ifdef mlarge
+ .model large
+ ARG equ 6
+ endif
+
+ ;-------------------------
+
+ ; The Microsoft startup code calls __setenvp and then __setargv. Each of
+ ; these can return a changed stack pointer. The routines set ___argv,
+ ; ___argc, and environ.
+
+
+ .DATA
+
+ If @codesize
+ return_adr dd ?
+ Else
+ return_adr dw ?
+ Endif
+
+ extrn __psp:word ; our PSP segment, set by startup before __setenvp
+ extrn ___argc:word ; pointer to argv[], used by startup in calling main
+ extrn _environ:word ; ptr to environment ptrs, used by startup calling main
+ extrn STKHQQ:word ; top of stack, defined by Microsoft C startup
+ extrn __osversion:word ; MS-DOS version
+
+ gseg dw ? ; segment of buffer passed to MKS glob
+
+ Public _com_slashc
+ _com_slashc db '/c', 0 ; default switch for command.com
+
+ .CODE
+ extrn ___setargv:proc ; Microsoft globber, in C library
+ extrn __amsg_exit:proc ; Microsoft stack overflow death, in C library
+
+ extrn _mks_init:proc ; C code to do MKS argument analysis
+ extrn _mks_globber:proc ; C code to run MKS glob.exe
+
+ DONT_USE equ 400h ; stack space that must be left over after
+ ; processing arguments
+
+ ; Define MIN_DOS_VER to be minimum version of DOS to support times 100,
+ ; using the -D assembler option. If undefined, assume 2.0.
+
+ Ifndef MIN_DOS_VER
+ MIN_DOS_VER Equ 200 ; have to at least have handle I/O, in ver 2.00
+ Endif
+
+ If MIN_DOS_VER lt 300
+ exec_ss dw ? ; needed to support DOS 2.xx exec system call
+ exec_sp dw ?
+ Endif
+
+ Public __setenvp
+
+ __setenvp Proc
+ pop ax
+ mov word ptr return_adr,ax
+ If @codesize
+ pop ax
+ mov word ptr return_adr + 2,ax
+ Endif
+
+ mov ax,3000h ; get MS-DOS version.
+ int 21h
+ mov __osversion,ax ; Microsoft code we're replacing does this, too.
+ mov dx,ax
+ xchg dl,dh ; version from DOS is in wrong byte order!
+ cmp dx,MIN_DOS_VER ; Approprite DOS version
+ jae ver_okay
+ mov bx,4 ; error message number
+ jmp version_death
+
+ ver_okay:
+ cmp al,4 ; if version 4 or beyond ignore switch char
+ jae ver_4
+ mov ax,3700h ; get switch char, usually / or -
+ int 21h
+ mov _com_slashc,dl ; set the switch character
+
+ ver_4:
+ mov ax,STKHQQ ; min SP: below this is stack overflow
+ add ax,DONT_USE ; retain some space, AX will be mks_init's SP
+ cmp sp,ax ; make sure that DONT_USE doesn't exhaust the stack
+ jb too_little ; sorry--expand the stack
+ mov dx,sp
+ sub dx,ax ; DX has amount of space mks_init can play with
+ mov sp,ax ; allocate that space for mks_init
+ push dx ; tell C program how much space he gets
+
+ call _mks_init ; parse envp and args, return stack space used
+ ; return -1 for insufficient stack space
+ pop dx ; total that was available
+
+ cmp ax,0FFFFh ; was there enough space?
+ je not_enough
+
+ sub dx,ax ; subtract off amount actually used
+ add sp,dx ; reduce stack by amount not used
+
+ cmp ___argc,0 ; did we find the MKS arguments?
+ jnz done_with_args
+
+ sub sp,dx ; reallocate the remaining space
+ push dx ; tell mks_globber how big it is
+ call _mks_globber ; try running MKS glob program
+ pop dx ; total that was available
+
+ cmp ax,0FFFFh ; was there enough space?
+ je not_enough
+
+ sub dx,ax ; subtract off amount actually used
+ add sp,dx ; reduce stack by amount not used
+
+ mov ax,gseg
+ or ax,ax
+ jz gspace_freed
+ mov es,ax
+ mov ah,49h ; free the memory block used by glob
+ int 21h
+
+ gspace_freed:
+ cmp ___argc,0 ; did MKS glob program succeed?
+ jnz done_with_args
+
+ ; Last chance, and it's a poor third choice, is to let Microsoft's globber run
+ ; It won't handle single quotes and thinks *.* matches abc and that * doesn't
+ ; match "abc.c". It will also change the file names to upper case. If
+ ; someone doesn't like that he can write a globber.
+
+ call ___setargv
+
+ done_with_args:
+ jmp return_adr
+
+ not_enough:
+ add sp,dx ; recover all the space that was allocated
+
+ too_little:
+ xor ax,ax ; message zero
+ jmp __amsg_exit ; stack overflow message and die
+ __setenvp Endp
+
+ ; Resolve Microsoft C's need for the following routine
+
+ Public __setargv
+
+ __setargv Proc
+ ret ; all was done by _setenvp
+ __setargv Endp
+
+ .DATA
+
+ fcb_one db 0, 12 dup(' ')
+ fcb_two db 0, 12 dup(' ')
+
+ gtt db 1, ' ', '\r', '\n' ; glob's tail is null
+
+ genv dw ? ; segment of glob's environment
+ gtail dd gtt ; pointer to glob's command tail
+ gfcb1 dd fcb_one ; first FCB
+ gfcb2 dd fcb_two ; second FCB
+
+ .CODE
+
+ ; Subroutine to get space for running MKS glob program.
+ ; Can't be using malloc() this early, so we call DOS directly.
+ ; Return a far pointer to the allocated 8K space, 0 for failure.
+
+ Public _get_glob_space
+ _get_glob_space Proc
+ mov ah,48h ; MS-DOS allocate memory call
+ mov bx,201h ; 8 Kilobytes worth of paragraphs plus one paragraph
+ ; the extra paragraph is used for glob's environment
+ int 21h
+ jnc got_it
+ sub ax,ax ; not enough memory
+ mov dx,ax
+ ret
+
+ got_it:
+ mov gseg,ax ; save segment address
+ mov dx,ax ; return segment address
+ sub ax,ax ; offset is always zero
+ ret
+ _get_glob_space Endp
+
+ ; Run the MKS glob program.
+ ; Arguments are standard pointer to the glob program name and far
+ ; pointer to the glob buffer.
+
+ Public _spawn_mks_glob
+
+ one_dig Proc Near ; convert to ascii and store 1 hex digit
+ mov ax,dx
+ and ax,0fh
+ add ax,30h
+ cmp ax,39h
+ jbe one_dec
+ add ax,7 ; change 3A to 41 ('A'), 3B to 'B' etc.
+
+ one_dec:
+ mov es:[bx],al
+ dec bx
+ shr dx,cl
+ ret
+ one_dig Endp
+
+ _spawn_mks_glob Proc
+ push bp
+ mov bp,sp
+ push si
+ push di
+
+ mov ax,gseg ; segment of glob buffer
+ mov dx,ax ; save for making ascii string
+ add ax,200h ; segment of where we'll put the environment
+ mov genv,ax
+
+ mov es,ax
+ mov cx,4
+ mov bx,3
+ call one_dig
+ call one_dig
+ call one_dig
+ call one_dig
+ mov es:word ptr [4],3030h ; we know glob buffer starts at para address
+ mov es:word ptr [6],3030h
+ mov es:byte ptr [8],0 ; terminate the string
+
+ mov ax,@data ; set ES:BX pointing to spawn parameter block
+ mov es,ax
+ lea bx,genv
+
+ If @datasize
+ mov ds,[bp+ARG+2] ; segment of program name
+ Endif
+ mov dx,[bp+ARG] ; offset of program name
+
+ If MIN_DOS_VER lt 300
+ ; DOS 2.x is brain-damaged and will clobber all but CS:IP
+ push ds
+ mov exec_ss,ss
+ mov exec_sp,sp
+ Endif
+ mov ax,4b00h ; spawn the glob program
+ int 21h ; we're assuming DOS 3.0+; 2.x trashes regs
+ If MIN_DOS_VER lt 300
+ mov ss,exec_ss ; will delay interrupts til after next instr
+ mov sp,exec_sp ; movs and pops don't change CF
+ pop ds
+ Endif
+ mov ah,0ffh ; assume failure: note doesn't affect carry
+ jc spawn_done ; problem: return MS-DOS error code
+
+ mov ah,4dh ; get return code of glob
+ int 21h
+
+ spawn_done: ; return code in AX, if spawn failed, AH == 0FFh
+ mov cx,ss
+ mov ds,cx
+
+ pop di
+ pop si
+ pop bp
+ ret
+ _spawn_mks_glob Endp
+
+ ; Catastophe calling glob.exe. Print message and die
+
+ .DATA
+
+ gmsg0 db 'glob: not found', 13, 10
+ gmsg1 db 'glob: insufficient space', 13, 10
+ gmsg2 db 'glob: unknown problem', 13, 10
+ gmsg3 db 'glob: arg list too long', 13, 10
+ gmsg4 db 'DOS '
+ db (MIN_DOS_VER shr 8) or 30h ; ascii major
+ db '.'
+ db ((MIN_DOS_VER and 0f0h) shr 4) or 30h ; ascii minor (tens)
+ db (MIN_DOS_VER and 0fh) or 30h ; ascii minor (units)
+ db ' or better required', 13, 10
+
+ gmsg dw gmsg0, gmsg1, gmsg2, gmsg3, gmsg4
+ dw gmsg
+
+ .CODE
+
+ Public _glob_problem
+ _glob_problem Proc
+ push bp
+ mov bp,sp
+ mov bx,[bp+ARG] ; get message index
+
+ version_death:
+ shl bx,1 ; convert to word index
+ mov dx,[bx].gmsg ; get offset of the message
+ mov cx,[bx+2].gmsg ; get offset of next message
+ sub cx,dx ; bytes in between
+ mov bx,2 ; write to stderr
+ mov ah,40h
+ int 21h
+
+ mov ax,4c01h ; terminte with return code 1
+ int 21h
+ ; no return
+ _glob_problem Endp
+
+
+ End